home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / public / bit / src / init.c < prev    next >
C/C++ Source or Header  |  1994-08-01  |  26KB  |  1,080 lines

  1. /*
  2.  * $Id: init.c,v 0.91 1994/02/20 00:52:57 zhao Pre-Release $
  3.  *
  4.  *. This file is part of BIT shareware package. After the two weeks of
  5.  *  free evaluation period, you are encouraged (required) to register
  6.  *  your copy for a small registration fee, which is $35 for personal use
  7.  *  and $50 for commercial, government and institutional use.
  8.  *
  9.  *  Copyright(c) 1993, 1994 by T.C. Zhao.
  10.  *  All rights reserved.
  11.  *
  12.  *  Permission to use, copy, and distribute this software in its entirety
  13.  *  for non-commercial purposes is hereby granted, provided that the
  14.  *  above shareware and copyright notices and this permission notice
  15.  *  appear in all copies and their documentation.
  16.  *
  17.  *  This software may be modified for your own use, but modified versions
  18.  *  may not be distributed without prior consent of the author.
  19.  *
  20.  *  This software is provided "as is" without expressed or implied
  21.  *  warranty of any kind.
  22.  *
  23.  *.
  24.  *
  25.  * Initialization: process, graphics, forms.
  26.  *
  27.  */
  28. #if !defined(lint) && defined(F_ID)
  29. char *id_init = "$Id: init.c,v 0.91 1994/02/20 00:52:57 zhao Pre-Release $";
  30. #endif
  31.  
  32. #include "bit.h"
  33. #include "extern.h"
  34. #include <stdlib.h>
  35. #include "dmalloc.h"
  36. #include <sys/types.h>
  37. #include <sys/signal.h>
  38. #include <signal.h>
  39. #include <setjmp.h>
  40.  
  41. /************ Local functions ***********************************/
  42.  
  43. static void non_graphics_init(void);
  44. static void check_graphics_cap(void);
  45. static void init_configsys(void);
  46.  
  47. /****************************************************************
  48.  * Global interface: do all the initialization, except for fonts
  49.  * which are done in text.c
  50.  *****************************************************************/
  51.  
  52. void
  53. bit_init(void)
  54. {
  55.     /* message generation threshold */
  56.     set_msg_threshold(verbose);
  57.  
  58.     /* where error messages go */
  59.     set_err_msg_fp(stderr);
  60.  
  61.     /* initialize signal handlers and other things */
  62.     non_graphics_init();
  63.  
  64.     /*
  65.      * initialize graphics default and forms library. If foreground is
  66.      * requested, do it here as check_graphics_cap calls winopen (the first
  67.      * one) to save current colormap
  68.      */
  69.  
  70.     if (!run_in_background)
  71.     foreground();
  72.  
  73.     check_graphics_cap();
  74.  
  75.     gui_init();
  76.  
  77.     /* show initial window */
  78.     open_main_window(imgptr);
  79.  
  80.     if (!no_panel)
  81.     show_info_window(-1, -1, -1, -1, 1);
  82.  
  83.     if (showedit && !no_panel)
  84.     show_control_window(-1, -1, -1, -1, 0);
  85.  
  86.     init_configsys();
  87. }
  88.  
  89. /*******************************************************************
  90.  * following signal will be trapped and program will exit upon receiving
  91.  * any of these. If SEGV or BUS is received, also send a messag to me.
  92.  *********************************************************************/
  93.  
  94. typedef struct
  95. {
  96.     int sig;
  97.     const char *text;
  98. }
  99. SIGTEXT;
  100.  
  101. static SIGTEXT stext[] =
  102. {
  103.     {SIGILL, "Illegal instruction"},
  104.     {SIGBUS, "Bus error"},
  105.     {SIGSEGV, "Segmentation violation"},
  106.     {SIGUSR1, "USR1--Killed by child"},    /* what was used for */
  107.     {SIGUSR2, "USR2--Q reset by child"}    /* Not used          */
  108. };
  109.  
  110. static int total = sizeof(stext) / sizeof(SIGTEXT);
  111.  
  112. #ifdef MAIL_AUTHOR
  113. static const char *myaddress = "zhao@bragg.phys.uwm.edu";
  114. #endif
  115.  
  116. /*************************************************************
  117.  * all signals ended up here
  118.  **************************************************************/
  119. static void
  120. sig_handler(int sig)
  121. {
  122.     SIGTEXT *st = stext + total;
  123.     char buf[200];
  124.  
  125.     /*
  126.      * Echo what kind of signal is received. Note that this might not work if
  127.      * segv or busE
  128.      */
  129.  
  130.     while (--st >= stext)
  131.       {
  132.       if (st->sig == sig)
  133.           M_info("SigH", "Received SIG=%d %s", sig, st->text);
  134.       }
  135.  
  136.     /* handle this signal */
  137.     switch (sig)
  138.       {
  139.       case SIGUSR2:
  140.       case SIGUSR1:        /* child will send this one */
  141.       break;
  142.  
  143.       case SIGSEGV:        /* hell breaks loose */
  144.       fputs("InternalError: Segmentation violation\n", stderr);
  145. #ifdef MAIL_AUTHOR
  146.       sprintf(buf, "echo 'segv %s' | Mail -s 'segv' %s 1>%s 2>&1",
  147.           rm_rcs_kw(sver), myaddress, "/dev/null");
  148.       (void) system(buf);
  149. #endif
  150.       break;
  151.  
  152.       case SIGBUS:
  153.       fputs("InternalError: Bus error\n", stderr);
  154. #ifdef MAIL_AUTHOR
  155.       sprintf(buf, "echo 'BusE %s' | Mail -s 'BusE' %s 1>%s 2>&1",
  156.           rm_rcs_kw(sver), myaddress, "/dev/null");
  157.       (void) system(buf);
  158. #endif
  159.       break;
  160.  
  161.       default:
  162.       fprintf(stderr, "Unknowm signal %d\n", sig);
  163.       break;
  164.       }
  165.  
  166.     clean_up();
  167. }
  168.  
  169. /*******************************************************************
  170.  * Quit immediately if basic assumption of the system is wrong.
  171.  * currently not likely (possible ?)
  172.  ******************************************************************/
  173.  
  174. static void
  175. check_basic_assumptions(void)
  176. {
  177.     /* getmat and submat (maybe others assume the following) */
  178.     if ((sizeof(char *) != sizeof(short *)) ||
  179.       (sizeof(char *) != sizeof(long *)) ||
  180.       (sizeof(char *) != sizeof(char **)))
  181.       {
  182.       fputs("Sorry. Wrong assumptions", stderr);
  183.       exit(0);
  184.       }
  185. }
  186.  
  187. /*******************************************************************
  188.  * initialize all stuff not related to graphics
  189.  *******************************************************************/
  190.  
  191. static void
  192. non_graphics_init(void)
  193. {
  194.     SIGTEXT *st = stext + total;
  195.  
  196.     check_basic_assumptions();
  197.  
  198.     /* install signal handlers */
  199.  
  200.     while (--st >= stext)
  201.     signal(st->sig, sig_handler);
  202.  
  203. #ifdef CORE
  204.     /* dump core if requested */
  205.     signal(SIGSEGV, SIG_DFL);
  206.     signal(SIGBUS, SIG_DFL);
  207. #endif
  208.  
  209.     /* get_mem_imgptr quits if unable to get it */
  210.  
  211.     imgptr = get_mem_imgptr();
  212.     imgptr->cmap = get_mem_cmap();
  213.  
  214. #ifdef PROTECT
  215.     protect();
  216. #endif
  217.  
  218. }
  219.  
  220. /*****************************************************************
  221.  * Check and maybe choose optimal graphics configurations
  222.  *****************************************************************/
  223.  
  224. static void
  225. check_graphics_cap(void)
  226. {
  227.     int n;
  228.  
  229.     if (getgdesc(GD_BITS_NORM_SNG_RED) == 0)
  230.       {
  231.       fputs("RGBmode is not available\n", stderr);
  232.       exit(0);
  233.       }
  234.  
  235.  
  236.     /*
  237.      * turn double buffer on only if capable. Would rather look ugly and
  238.      * flickering than wrong
  239.      */
  240.  
  241.     double_buf = double_buffer_capable();
  242.  
  243.  
  244. #ifndef NO_NP_DBL
  245.     simu_dbl_buffer = 1;
  246. #endif
  247.  
  248. #ifndef NO_OP_DBL
  249.     /*
  250.      * due to some reason, simulation does not work well in pupdraw. need to
  251.      * check some more. turn it off
  252.      */
  253.     simu_op_dblbuf = getgdesc(GD_BITS_OVER_SNG_CMODE) > 1;
  254. #endif
  255.  
  256.     if ((n = getgdesc(GD_BITS_NORM_SNG_CMODE)) < CMAPBITS && n >= 9)
  257.       {
  258.       fprintf(stderr, "Please change CMAPBITS in utype.h from %d to %d\n",
  259.           CMAPBITS, n);
  260.       }
  261.  
  262.     n = getgdesc(GD_BITS_NORM_SNG_CMODE);
  263.  
  264.     errno = 0;
  265.  
  266.     M_info("Init", "SingleBuffer CMAPbits: %d", n);
  267.  
  268.     if (n < 9 || CMAPBITS < 9)
  269.       {
  270.       if (verbose > 1)
  271.           fputs("CMAPBITS < 9. Performance untested\n", stderr);
  272.  
  273.       if (CMAPBITS < 8)
  274.         {
  275.         fputs("BIT can't work with less than 8 bits\n", stderr);
  276.         exit(1);
  277.         }
  278.       }
  279.  
  280.     M_info("Init", "%s in double buffer mode", double_buf ? "" : "Not");
  281.  
  282.     /* check anti-aliasing capabilities */
  283.  
  284.     smooth_lines = sml_capable();
  285.     M_info("Init", "smooth line is %ssupported", smooth_lines ? "" : "not ");
  286.  
  287.     /* save current system map for later restore */
  288.     get_sysmap();
  289. }
  290.  
  291.  
  292. /*************************************************************
  293.  * read n positive integers. If an error occurs, skip to the
  294.  * the end of the line.
  295.  **************************************************************/
  296.  
  297. static int
  298. readnint(FILE * fp, int n, int x[])
  299. {
  300.     int i, err;
  301.     for (i = err = 0; !err && i < n; i++)
  302.     err = ((x[i] = readpint(fp)) < 0);
  303.  
  304.     /* skip until either the end of line or EOF */
  305.     if (err)
  306.     while ((i = getc(fp)) != EOF && i != '\n')
  307.         ;
  308.     return err;
  309. }
  310.  
  311.  
  312. /********************************************************************
  313.  * bring up the main viewing window and possibly set all inital
  314.  * panel locations
  315.  ********************************************************************/
  316.  
  317. static const char *winposfile = "WinPosition";
  318.  
  319. /*********************************************************************
  320.  * Read initial window placement from startup file if requested
  321.  ********************************************************************/
  322. static void
  323. read_win_pos(void)
  324. {
  325.     int xy[4];
  326.     int prefp = !auto_position && !full_win;
  327.     FILE *fp = 0;
  328.  
  329.     if ((fp = get_BITfile_fp(winposfile, "r")))
  330.       {
  331.       int readok = readnint(fp, 4, xy) == 0;
  332.  
  333.       if (verbose > 1)
  334.           fprintf(stderr, "%s %s read\n", winposfile,
  335.               readok ? "OK" : "Bad");
  336.  
  337.       if (readok && prefp)
  338.         {
  339.         win_xo = xy[0];
  340.         win_yo = xy[1];
  341.         win_w = xy[2];
  342.         win_h = xy[3];
  343.         }
  344.       }
  345.  
  346.     /* get default panel positions */
  347.     xy[0] = xy[2] = -1;
  348.     xy[1] = 5;
  349.     xy[3] = 350;
  350.  
  351.     if (fp)
  352.       {
  353.       readnint(fp, 4, xy);
  354.       fclose(fp);
  355.       }
  356.  
  357.     /* the info panel */
  358.     set_info_window_position(xy[0], xy[1]);
  359.  
  360.     /* the control panel */
  361.     set_control_window_position(xy[2], xy[3]);
  362. }
  363.  
  364. void
  365. open_main_window(IPTR im)
  366. {
  367.     int dx = 285;
  368.     int bk = 10, g_xmax, g_ymax;
  369.     char *ttt = rm_rcs_kw(sver);
  370.     char tbuf[512];
  371.  
  372.     /*
  373.      * if fit_image_size == 2, always force the window size to be that of the
  374.      * image. Also need to demand image ready status to avoid flashing
  375.      */
  376.  
  377.     if (win_id > 0)
  378.       {
  379.       /* demand ready status */
  380.       if (fit_image_size == 2 && im && im->ok)
  381.         {
  382.         long x, y;
  383.         set_current_window(win_id);
  384.         getorigin(&x, &y);
  385.         win_w = im->w;
  386.         win_h = im->h;
  387.         winposition(x, x + win_w - 1, y, y + win_h - 1);
  388.         }
  389.       return;
  390.       }
  391.  
  392.     screen_xp = g_xmax = getgdesc(GD_XPMAX);
  393.     screen_yp = g_ymax = getgdesc(GD_YPMAX);
  394.  
  395.     show_clock_mailbox(g_xmax - 200, g_ymax - 120, 0, 0);
  396.  
  397.     /* default window position and size */
  398.  
  399.     win_xo = win_yo = bk;
  400.  
  401.     if (fit_image_size)
  402.       {
  403.       if (!im || im->type == T_FLEX || im->w <= 1)
  404.         {
  405.         read_win_pos();    /* needed to set panel pos */
  406.         return;
  407.         }
  408.  
  409.       win_w = im->w;
  410.       win_h = im->h;
  411.       }
  412.     else
  413.       {
  414.       win_w = g_xmax - ((full_win) ? 2 * bk : dx);
  415.       win_h = g_ymax - 40;
  416.       }
  417.  
  418.     /* read_win_pos will do proper thing if !fit_image */
  419.     if (!fit_image_size)
  420.     read_win_pos();
  421.  
  422.     /* final constraints */
  423.     if (win_w > g_xmax)
  424.     win_w = g_xmax;
  425.     if (win_h > g_ymax)
  426.     win_h = g_ymax;
  427.  
  428.  
  429. #ifndef REGISTERED
  430.     {
  431.     strcat(strcpy(tbuf, ttt), "-- ");
  432.     ttt = strcat(tbuf, unreg);
  433.     }
  434. #endif
  435.  
  436.     prefposition(win_xo, win_w + win_xo - 1, win_yo, win_h + win_yo - 1);
  437.  
  438.     if ((win_id = winopen(ttt)) < 0)
  439.       {
  440.       fputs("Error opening window\n", stderr);
  441.       clean_up();
  442.       }
  443.     wintitle(ttt);
  444.  
  445.     M_info("Init", "ScreenSize %dX%d", screen_xp, screen_yp);
  446.  
  447.     /* make the window size changeable */
  448.     minsize(60, 60);
  449.     iconsize(110, 89);
  450.     winconstraints();
  451.  
  452.     if (double_buf)
  453.     doublebuffer();
  454.  
  455.     /*
  456.      * initialize cursor, overplane. Must come after the graphics system is
  457.      * initialized, say by a winopen
  458.      */
  459.  
  460.     glu_init();
  461.  
  462.     /*
  463.      * must call gconfig here regardless if double buffer because glu_init
  464.      * might've called other configuration routine
  465.      */
  466.  
  467.     gconfig();
  468.  
  469.     /* clear screen */
  470.     clear_over_pup();
  471.     set_bk_color(background_color);
  472.     clear_screen(win_id, 1);
  473.  
  474.  
  475.     /* queue all devices */
  476.     fl_qdevice(RIGHTMOUSE);
  477.     fl_qdevice(MIDDLEMOUSE);
  478.     fl_qdevice(LEFTMOUSE);
  479.  
  480.     fl_qdevice(CKEY);        /* current image   */
  481.     fl_qdevice(SPACEKEY);    /* next image      */
  482.     fl_qdevice(PKEY);        /* previous image  */
  483.     fl_qdevice(MKEY);        /* show menu       */
  484.     fl_qdevice(SKEY);        /* slides mode off */
  485.  
  486.     fl_qdevice(F1KEY);        /* used internally */
  487.  
  488.     fl_qdevice(KEYBD);
  489.     fl_qdevice(PAUSEKEY);
  490.     fl_qdevice(LEFTCTRLKEY);
  491.     fl_qdevice(RIGHTCTRLKEY);
  492.     fl_qdevice(LEFTALTKEY);
  493.     fl_qdevice(WINTHAW);
  494.     fl_qdevice(WINFREEZE);
  495.     fl_qdevice(WINQUIT);
  496.     fl_qdevice(WINSHUT);
  497.     fl_qdevice(LEFTARROWKEY);
  498.     fl_qdevice(UPARROWKEY);
  499.     fl_qdevice(DOWNARROWKEY);
  500.     fl_qdevice(RIGHTARROWKEY);
  501.  
  502. }
  503.  
  504.  
  505. /**************************************************************
  506.  * save current window locations
  507.  **************************************************************/
  508.  
  509. /*ARGSUSED */
  510. int
  511. save_win_position(int n)
  512. {
  513.     long owin = winget();
  514.     FILE *fp;
  515.  
  516.     if (!(fp = get_BITfile_fp(winposfile, "w")))
  517.       {
  518.       Bark("SaveWinPos", "Bad open");
  519.       return -1;
  520.       }
  521.  
  522.     set_current_window(win_id);
  523.     getorigin(&win_xo, &win_yo);
  524.     getsize(&win_w, &win_h);
  525.     fprintf(fp, "%ld %ld %ld %ld # MainWindow Location & Size\n",
  526.         win_xo, win_yo, win_w, win_h);
  527.  
  528.     write_info_window_position(fp);
  529.     write_control_window_position(fp);
  530.     fclose(fp);
  531.  
  532.     set_current_window(owin);
  533.  
  534.     return 0;
  535. }
  536.  
  537. /************************************************************
  538.  * get screen information. Maybe used by PostScript routine
  539.  *************************************************************/
  540. int
  541. get_scr_dpi(void)
  542. {
  543.     int xm = getgdesc(GD_XMMAX);
  544.     int ym = getgdesc(GD_YMMAX);
  545.     int xdpi = ((float) getgdesc(GD_XPMAX) / (xm / 25.4) + 0.5);
  546.     int ydpi = ((float) getgdesc(GD_YPMAX) / (ym / 25.4) + 0.5);
  547.  
  548.     if (Abs(xdpi - ydpi) > 5)
  549.       {                /* non-square pixel */
  550.       M_info("ScrDPI", "Non-Square Pixel: Xdpi=%d Ydpi=%d", xdpi, ydpi);
  551.       }
  552.  
  553.     return (xdpi + ydpi) / 2;
  554. }
  555.  
  556.  
  557. /***************************************************************
  558.  * show  clock and mailbox
  559.  ***************************************************************/
  560. #include <stdio.h>
  561. #include <stdlib.h>
  562. #include <string.h>
  563. #include "unistd.h"
  564. #include <sys/types.h>
  565. #include <signal.h>
  566.  
  567. /******************************************************************
  568.  * in bit, only one copy of clock_mail is allowed to run.
  569.  * This is the lock file, which also contains the PID of clock_mail,
  570.  * in case clockmail wants to check if the said process is still
  571.  * alive.
  572.  ******************************************************************/
  573. #ifndef LOCK_FILE
  574. #define LOCK_FILE ".iclock.lc"
  575. #endif
  576.  
  577. /* name of the program to run */
  578. #ifndef CLOCK_MAIL
  579. #define CLOCK_MAIL "clockmail"
  580. #endif
  581.  
  582. static char local[150];
  583. static int gid, pid, cid;
  584.  
  585. void
  586. show_clock_mailbox(int x, int y, int w, int h)
  587. {
  588.     static int lx = -1, ly, lw, lh;
  589.  
  590.     pid = getpid();
  591.     gid = setpgrp();
  592.  
  593.     if (no_panel || no_clockmail)
  594.     return;
  595.  
  596.     /*
  597.      * due to further forking in clock_mailbox, the fork does not give the
  598.      * correct process id. We can get it from the lockfile of the
  599.      * clock_mailbox
  600.      */
  601.  
  602.     if (fork() == 0)
  603.       {
  604.       if (x > 0 && y > 0)
  605.         {
  606.         lx = x;
  607.         ly = y;
  608.         lw = w;
  609.         lh = h;
  610.         sprintf(local, "%s -fb -p %d  %d %d %d %d", CLOCK_MAIL, pid,
  611.             x, y, w, h);
  612.         }
  613.       else if (lx >= 0)
  614.         {
  615.         sprintf(local, "%s -fb -p %d  %d %d %d %d", CLOCK_MAIL, pid,
  616.             lx, ly, lw, lh);
  617.         }
  618.       else
  619.         {
  620.         sprintf(local, "%s -fb -p %d  ", CLOCK_MAIL, pid);
  621.         }
  622.       (void) execlp("/bin/sh", CLOCK_MAIL, "-c", local, (char *) 0);
  623.       perror("execl");
  624.       }
  625.  
  626.     if (x > 0 && y > 0)
  627.       {
  628.       lx = x;
  629.       ly = y;
  630.       lw = w;
  631.       lh = h;
  632.       }
  633.  
  634. }
  635.  
  636. /* kill clock_mail when bit quits */
  637. void
  638. process_clean_up(void)
  639. {
  640.     if (run_in_background)
  641.       {
  642.       if (kill(0, SIGKILL))
  643.           perror("killgid0");
  644.       }
  645. }
  646.  
  647. static char lockfile[1024];
  648.  
  649. void
  650. remove_clock_mailbox(void)
  651. {
  652.     char line[150];
  653.  
  654.     cid = -1;
  655.  
  656.     /* generate the lock filename */
  657.     if (lockfile[0] == '\0')
  658.       {
  659.       strncpy(lockfile, getenv("HOME"), sizeof(lockfile));
  660.       lockfile[sizeof(lockfile) - 1] = '\0';
  661.       strncat(lockfile, "/", sizeof(lockfile) - 1);
  662.       strncat(lockfile, LOCK_FILE, sizeof(lockfile) - 1);
  663.       }
  664.  
  665.     /* check if the process is still alive */
  666.     if (access(lockfile, R_OK) == 0)
  667.       {
  668.       FILE *fp = fopen(lockfile, "r");
  669.       fgets(line, sizeof(line), fp);
  670.       fclose(fp);
  671.       cid = atoi(line);
  672.       }
  673.  
  674.     /* kill it. clockmail will cleanup the lockfile */
  675.     if (cid > 0)
  676.     kill(cid, SIGUSR1);
  677. }
  678.  
  679. /*******************************************************************
  680.  * Configure
  681.  *******************************************************************/
  682.  
  683. static int cm = -1;
  684. static int cfg_zoomx, cfg_zoomy;
  685.  
  686. /* built-in Pause in SlideShow mode, in milli-second */
  687. static int fpause[] =
  688. {
  689.     0, 20, 50, 100, 200, 500, 1000, 2000, 5000, 10000, 60000, -1
  690. };
  691.  
  692. void
  693. slideshow_off(void)
  694. {
  695.     slide_pause_index = 0;
  696.     slideshow = 0;
  697. }
  698.  
  699. /**********************************************************************
  700.  * given slide show pausing intervals, generate the string version of it.
  701.  * the function is complicated by the fact that command line might set the
  702.  * interval to something not in the table, we use the last slot for it
  703.  **********************************************************************/
  704.  
  705. static const char *
  706. gpause_string(void)
  707. {
  708.     static char localstr[120];
  709.     char pp[20];
  710.     int i, delta = 100000;
  711.     int npause = sizeof(fpause) / sizeof(fpause[0]);
  712.  
  713.     localstr[0] = '\0';
  714.  
  715.     strcpy(localstr, "Off");
  716.     for (i = 0; i < npause; i++)
  717.       {
  718.       if (fpause[i] > 0)
  719.         {
  720.         sprintf(pp, "|%.2fs", (float) fpause[i] * 0.001);
  721.         strcat(localstr, pp);
  722.         if (delta < Abs(slideshow - fpause[i]))
  723.           {
  724.               delta = Abs(slideshow - fpause[i]);
  725.               slide_pause_index = i;
  726.           }
  727.         }
  728.       }
  729.  
  730.     if (delta && slideshow)
  731.       {                /* command line has set it */
  732.       fpause[npause - 1] = slideshow;
  733.       sprintf(pp, (slideshow > 99) ? "|%.1fs" : "|%.2fs",
  734.           (float) fpause[npause - 1] * 0.001);
  735.       strcat(localstr, pp);
  736.       slide_pause_index = npause - 1;
  737.       }
  738.  
  739.     return localstr;
  740. }
  741.  
  742. /*********************************************************************
  743.  * built-in percentages for progress report
  744.  *********************************************************************/
  745.  
  746. static int report_percent[] =
  747. {
  748.     0, 2, 5, 10, 20
  749. };
  750.  
  751. static const char *
  752. greport_string(void)
  753. {
  754.     return "Off|2%|5%|10%|20%";
  755. }
  756.  
  757. /****************************************************************
  758.  * the configuration structure. If opt is null, function gopt
  759.  * is called to get the option string. This way we localize
  760.  * the option change to the defination file
  761.  *****************************************************************/
  762.  
  763. typedef struct
  764. {
  765.     const char *vstr;        /* variable name                   */
  766.     const char *exp1, *exp2;    /* brief explanatin                */
  767.     int *var, val;        /* the variable. Val unused        */
  768.     const char *opt;        /* string version of values        */
  769.     const char *(*gopt) (void);    /* funciton that generates strings */
  770. }
  771. Opt_t;
  772.  
  773. #if defined(MTRACE)
  774. #define MMSG "Error|Warning|Info|Debug|Trace"
  775. #else
  776. #if defined(MDEBUG)
  777. #define MMSG "Error|Warning|Info|Debug"
  778. #else
  779. #define MMSG "Error|Warning|Info"
  780. #endif
  781. #endif
  782.  
  783. static int qdither_method;
  784. static Opt_t opt[] =
  785. {
  786.     {"DisplayStyle",
  787.      "Many styles to display an image. Block is the most efficient",
  788.      "While CYCLE will cycle thru all methods",
  789.      &display_style, 0, 0, gds_string
  790.     },
  791.  
  792. #ifndef SGL_BUF
  793.     {"DoubleBuffer",
  794.      "Turn double buffer on and off",
  795.      0,
  796.      &double_buf, 0, "Off|On", 0
  797.     },
  798. #endif
  799.  
  800.     {"AlwaysRefreshScreen",
  801.      "Controls if the screen should be refreshed",
  802.      "Before each display",
  803.      &always_clear, 0, "No|Yes", 0
  804.     },
  805.  
  806.     {"SlideShow",
  807.      "Interval between each frame, in seconds",
  808.      "",
  809.      &slide_pause_index, 0, 0, gpause_string
  810.     },
  811.  
  812.     {"ProgressReport",
  813.      "controls if to report progress and how frequent (in %).",
  814.      "This does not affect reporting by cursor",
  815.      &report_level, 0, 0, greport_string
  816.     },
  817.  
  818.     {"PSResolution",
  819.      "resolution to use when converting PS file to raster",
  820.      "large value will result in large image files",
  821.      &ps_res_index, 0, 0, gps_res_string,
  822.     },
  823.  
  824.     {"XMagnification",
  825.      "Magnification power in X-direction",
  826.      "Applicable in BLOCK display mode only",
  827.      &cfg_zoomx, 0, "Auto|1|2|3|4|5", 0
  828.     },
  829.  
  830.     {"YMagnification",
  831.      "Magnification power in Y-direction",
  832.      "Applicable in BLOCK display mode only",
  833.      &cfg_zoomy, 0, "Auto|1|2|3|4|5", 0
  834.     },
  835.  
  836.     {"AutoPan",
  837.      "",
  838.      "",
  839.      &always_pan, 0, "Never|SlidesOnly|Always", 0
  840.     },
  841.  
  842.     {"PreserveWMcolors",
  843.      "Controls if to preserve the colors window manager uses",
  844.      "via colormap re-ordering.",
  845.      &preserve_wm_colors, 0, "No|Yes", 0
  846.     },
  847.  
  848.     {"AlwaysUseBorder",
  849.      "This setting controls if all control panels should have a border",
  850.      "",
  851.      &always_border, 0, "No|Yes", 0
  852.     },
  853.  
  854.     {"ShowCutBuffer",
  855.      "Show current cut buffers while moving",
  856.      "Could be slow on old machines",
  857.      &show_cut_buffer, 0, "No|Yes", 0
  858.     },
  859.  
  860.  /*
  861.   * if simulate double buffering. Hardware doublebuffering, double_buf,
  862.   * overwrites this setting
  863.   */
  864.  
  865. #ifndef NO_NP_DBL
  866.     {"SimuDBLBuffer",
  867.      "Turn simulation of double buffering on and off",
  868.      0,
  869.      &simu_dbl_buffer, 0, "Off|On", 0
  870.     },
  871. #endif
  872.  
  873. #ifndef NO_OP_DBL
  874.     {"SimuOPDblBuf",
  875.      "Turn on and off the simulation of double buffering",
  876.      "in overlay/pupdraw",
  877.      &simu_op_dblbuf, 0, "Off|On", 0
  878.     },
  879. #endif
  880.  
  881.     {"AutoCropFill",
  882.      "Controls if to fill the portion outside the region of interest",
  883.      "",
  884.      &crop_fill, 0, "No|Ask|Yes", 0
  885.     },
  886.  
  887.  
  888.     {"AlwaysReadScrn",
  889.      "Controls the mode of operation for crop",
  890.      "If no, internal memory copy is used",
  891.      &always_readscrn, 0, "No|Yes", 0
  892.     },
  893.  
  894.     {"SmoothLines",
  895.      "To turn on and off anti-aliasing in line drawing",
  896.      "No effect if hardware is not capable",
  897.      &smooth_lines, 0, "Off|On", 0
  898.     },
  899.  
  900.     {"HalftoneMethod",
  901.      "", "",
  902.      &halftone_method, 0, 0, bw_dither_string
  903.     },
  904.  
  905.     {"QuantizationMethod",
  906.      "", "",
  907.      &quant_method, 0, 0, quant_opt_string
  908.     },
  909.  
  910.     {"QuantDither",
  911.      "", "",
  912.      &qdither_method, 0, 0, qdither_opt_string
  913.     },
  914.  
  915.     {"KeepTextAndSgf",
  916.      "Controls if text and simple geometric figures should be kept",
  917.      "across images",
  918.      &keepmisc, 0, "No|Yes", 0
  919.     },
  920.  
  921.  
  922.     {"DelFromDiskConfirm",
  923.      "Controls if confirmation should be asked",
  924.      "when deleting files from disk",
  925.      &always_delete, 0, "Yes|No", 0
  926.     },
  927.  
  928.  
  929.     {"AutoChangeExt",
  930.      "Change file extension according to its format when writing",
  931.      0,
  932.      &auto_ext, 0, "No|Yes", 0
  933.     },
  934.  
  935.     {"AutoRemoveFromList",
  936.      "If set, files that are in error will be removed from",
  937.      "the active list (no disk activities)",
  938.      &auto_remove, 0, "No|Ask|Yes", 0
  939.     },
  940.  
  941.     {"ReportMouseLocation",
  942.      "Controls report mouse location reporting and ",
  943.      "location origin",
  944.      &report_mouse, 0, "No|Window|Image", 0
  945.     },
  946.  
  947.     {"AutoRemoveIcon",
  948.      "controls if to delete image browser icon when orginial",
  949.      "image no long exists",
  950.      &auto_remove_thumbnail, 0, "No|Yes", 0
  951.     },
  952.  
  953.     {"MessageVerbosity",
  954.      "controls amount of the messages to be generated",
  955.      "Lots of messages if trace",
  956.      &verbose, 0, MMSG, 0
  957.     },
  958.  
  959.     {"ShowEditAuto",
  960.      "Whether bring up the edit panel automatically",
  961.      "upon start-up",
  962.      &showedit, 0, "No|Yes", 0
  963.     },
  964.  
  965.     {"ConfirmOnLoad",
  966.      "Whether to nag about image changes",
  967.      "when loading new files",
  968.      &abort_change_ask, 0, "No|Yes", 0
  969.     }
  970. };
  971.  
  972. static void
  973. init_configsys(void)
  974. {
  975.     int err, nopt = sizeof(opt) / sizeof(opt[0]);
  976.     Opt_t *p = opt, *ps;
  977.  
  978.     /* set error output routine default */
  979.     set_msg_threshold(verbose);
  980.     set_err_msg_fp(stderr);
  981.     set_read_silent(verbose == 0);    /* in ulib */
  982.     set_err_msg_func(TC_continue);
  983.     set_err_msg_brief(verbose <= 1);
  984.  
  985.     /*
  986.      * Note that every option should not have space in between as the option
  987.      * loading module can't read it. Space in front or end is ok.
  988.      */
  989.     if (cm < 0)
  990.       {
  991.       if ((cm = def_option("Setup", 0, "option.hlp")) < 0)
  992.         {
  993.         Bark("SetUp", "Unable to define menu");
  994.         return;
  995.         }
  996.  
  997.       set_option_act(cm, "SaveWinPos", save_win_position);
  998.  
  999.       for (err = 0, ps = p + nopt; !err && p < ps && p->vstr; p++)
  1000.         {
  1001.         if (!p->opt)
  1002.             p->opt = p->gopt ? p->gopt() : "Unkwnon";
  1003.         err = addto_option(cm, p->vstr, p->exp1, p->exp2,
  1004.                    p->var, p->opt, 0) < 0;
  1005.         }
  1006.  
  1007.       if (err)
  1008.         {
  1009.         M_warn("InitConfig", "Something is wrong");
  1010.         return;
  1011.         }
  1012.       }
  1013.     percent_report = report_percent[report_level];
  1014.     set_quant_parameters(-1, qdither_method, quant_method - 1);
  1015. }
  1016.  
  1017. /*******************************************************************
  1018.  * Override options either set via Startup file or command line.
  1019.  ******************************************************************/
  1020. void
  1021. hardware_constraints(int override)
  1022. {
  1023.     if (!double_buf && double_buffer_capable())
  1024.     M_info("Config", "Please turn double buffer on");
  1025.  
  1026.     /* double buffer might've been turned on */
  1027.     if (double_buf && !double_buffer_capable())
  1028.       {
  1029.  
  1030.  
  1031.       errno = 0;        /* shut up inaccurate reports */
  1032.  
  1033.       M_err("Config", "Not enuf bitplanes for double buffering");
  1034.  
  1035.       if (override)
  1036.           double_buf = 0;
  1037.       else
  1038.           M_err("Config", "Please turn dobule buffer off");
  1039.       }
  1040. }
  1041.  
  1042. void
  1043. config_sys(void)
  1044. {
  1045.     int lastdblbuf = double_buf;
  1046.  
  1047.     if (cm < 0)
  1048.     init_configsys();
  1049.  
  1050.     cfg_zoomx = (g_zoomx + 0.1);
  1051.     cfg_zoomy = (g_zoomy + 0.1);
  1052.  
  1053.  
  1054.     do_option(cm);
  1055.  
  1056.     /*** Some of the setting require immediate action. Do it now **/
  1057.  
  1058.     g_zoomx = cfg_zoomx;
  1059.     g_zoomy = cfg_zoomy;
  1060.  
  1061.  
  1062.     /* error message generation */
  1063.     set_msg_threshold(verbose);
  1064.     set_err_msg_brief(verbose <= 1);
  1065.  
  1066.     slideshow = fpause[slide_pause_index];
  1067.     percent_report = report_percent[report_level];
  1068.     set_quant_parameters(-1, qdither_method, quant_method - 1);
  1069.  
  1070.     /* final check to make sure everything is OK */
  1071.  
  1072.     hardware_constraints(1);
  1073.  
  1074.     /* if different request, re-configure and display */
  1075.     if ((lastdblbuf - double_buf))
  1076.     repaint(imgptr, win_id);
  1077.  
  1078.     return;
  1079. }
  1080.